package com.security.service;

import java.sql.SQLException;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import san.dao.system.ResourceDao;
import san.dao.system.RoleDao;
import san.dao.system.UserDao;
import com.security.domain.Resource;
import com.security.domain.Role;
import com.security.domain.User;
import com.security.resource.SecurityResourceCache;
import com.utils.encode.EncodeUtils;
import com.utils.CollectionUtils;
import com.utils.Page;

/**
 * 整个User模块内的业务逻辑Facade类. 组合user,role两者的DAO.DAO均直接使用泛型的SimpleHibernateTemplate.
 * 使用Spring的@Service/@Autowired 指定IOC设置. 使用Spring的@Transactional指定事务管理.
 * 
 * @author san
 */
@Service
@Transactional
@SuppressWarnings("unchecked")
public class UserService {
	@Autowired
	private UserDao userDao;
	@Autowired
	private RoleDao roleDao;
	@Autowired
	private ResourceDao resourceDao;
	
	@Transactional(readOnly = true)
	public User getUser(String id) {
		return userDao.get(id);
	}

	@Transactional(readOnly = true)
	public List<User> getUsers() throws Exception {
		return userDao.getAll();
	}

	@Transactional(readOnly = true)
	public Page<User> getAllUsers(final Page<User> page) {
		return userDao.getAll(page);
	}

	@Transactional(readOnly = true)
	public User getUserByLoginName(String loginName) {
		return userDao.findUniqueBy("username", loginName);
	}

	public void saveUser(User user) throws Exception {
		if (user.getPassword().length() < 32) {
			String psw = EncodeUtils.getMd5PasswordEncoder(
					user.getPassword(), user.getUsername());
			user.setPassword(psw);
		}
		List<Role> list = roleDao.findByIds(CollectionUtils
				.fetchPropertyToList(user.getRoles(), "id"));
		user.setRoles(list);
		userDao.save(user);
	}

	public void saveUser(User user, List ids) throws Exception {
		if (user.getPassword().length() < 32) {
			String psw = EncodeUtils.getMd5PasswordEncoder(
					user.getPassword(), user.getUsername());
			user.setPassword(psw);
		}
		List<Role> list = roleDao.findByIds(ids);
		user.setRoles(list);
		userDao.save(user);
	}

	public void deleteUser(String id) {
		userDao.delete(id);
	}

	/*
	 * 删除所有用户
	 */
	public void deleteAllUser() throws SQLException {
		userDao.batchExecute("delete User");
	}

	/*
	 * 删除所有角色
	 */
	public void deleteAllRole() throws SQLException {
		userDao.executeUpdateBySql("delete base_user_role");
		userDao.batchExecute("delete Role");
	}

	/*
	 * 删除所有资源
	 */
	public void deleteAllResource() throws SQLException {
		userDao.executeUpdateBySql("delete base_role_resource");
		userDao.batchExecute("delete Resource");
	}

	@Transactional(readOnly = true)
	public boolean isLoginNameUnique(String loginName, String orgLoginName) {
		return userDao.isPropertyUnique("loginName",loginName, orgLoginName);
	}

	@Transactional(readOnly = true)
	public List<Role> getAllRoles() {
		return roleDao.getAll();
	}

	@Transactional(readOnly = true)
	public Page<Role> getAllRoles(Page<Role> page) {
		return roleDao.getAll(page);
	}

	@Transactional(readOnly = true)
	public Role getRole(String id) {
		return roleDao.get(id);
	}

	public void saveRole(Role role) throws Exception {
		List<Resource> list = resourceDao.findByIds(CollectionUtils
				.fetchPropertyToList(role.getResources(), "id"));
		role.setResources(list);
		roleDao.save(role);
	}

	public void saveRole(Role role, List ids)throws Exception {
		List<Resource> list = resourceDao.findByIds(ids);
		role.setResources(list);
		roleDao.save(role);
	}

	public void deleteRole(String id) {
		roleDao.delete(id);
	}

	public void saveResource(Resource resource) {
		resourceDao.save(resource);
		SecurityResourceCache.removeCache(resource.getPath());
		SecurityResourceCache.putCache(resource);
	}

	public void deleteResource(String id) throws SQLException {
		resourceDao.executeUpdateBySql(
				"delete base_role_resource where res_id='" + id + "'");
		Resource resource = getResource(id);
		resourceDao.delete(resource);
		SecurityResourceCache.removeCache(resource.getPath());
	}

	@Transactional(readOnly = true)
	public List<Resource> getAllResources() {
		return resourceDao.getAll();
	}

	@Transactional(readOnly = true)
	public Page<Resource> getAllResources(Page<Resource> page) {
		page.setOrderBy("name");
		return resourceDao.getAll(page);
	}

	@Transactional(readOnly = true)
	public Resource getResource(String id) {
		return resourceDao.get(id);
	}

	public GrantedAuthority[] getAuthoritys(String resPath) {
		Resource resource = (Resource) resourceDao.findUniqueBy("path", resPath);
		GrantedAuthority[] gas = new GrantedAuthority[0];
		gas[0] = new GrantedAuthorityImpl(resource.getName());
		return gas;
	}

}
